package main

import (
	"fmt"
)

/*
Go 中没有关键字显式声明某个类型实现了某个接口。
只要一个类型实现了接口要求的所有方法，该类型就自动被认为实现了该接口。
*/
type Shape interface {
	getArea() float64
	getPerimeter() float64
}

type Circle struct {
	Radius float64 `json:"radius"`
	Age    int32   `json:"-"`
	name   string  `json:"name"`
}

func (c *Circle) getArea() float64 {
	var result float64
	result = (*c).Radius * (*c).Radius * 3.14
	return result
}

func (c *Circle) getPerimeter() float64 {
	var result float64
	result = 2 * 3.14 * (*c).Radius
	return result
}

func printValue(value interface{}) {
	fmt.Printf("Value = %v, Type = %T \n", value, value)
}


//接口嵌套
type Reader interface {
	Read() string
}

type Writer interface {
	Write(data string)
}

type ReadWriter interface {
	Reader
	Writer
}

type File struct {
	Data string `json:"data"`
}

func (file *File) Read() string {
	var result string
	result = "实现了阅读接口" + *&file.Data
	return result
}

func (file *File) Write(data string) {
	*&file.Data = data
	fmt.Printf("实现了写入接口,file.Data = %s",*&file.Data)
}

func main() {

	/*
		接口变量可以存储实现该接口的任意值。空接口 interface{} 是 Go 的特殊接口，表示所有类型的超集。
		接口变量实际上包含了两个部分：
		动态类型：存储实际的值类型。
		动态值：存储具体的值。
	*/
	var face1 interface{} //默认零值是nil
	fmt.Printf("face1 value = %v \n", face1)
	face1 = 16
	fmt.Printf("face1 value = %v, face1 type = %T \n", face1, face1)

	//接口本身已经是引用类型，因此不需要使用指向接口的指针（*ReadWriter）。
	var fwr ReadWriter = &File{Data: "数据文本1"}
	var f1 *File = &File{Data: "数据文本2"}
	var f2 *File
	var flag bool
	f2,flag = fwr.(*File)

	fmt.Println(fwr.Read())
	fmt.Println(f1.Read())
	if flag {
		fmt.Println(f2.Read())
	}
}
